package com.zp.self.module.level_4_算法练习.算法.排序;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;

import static java.lang.Thread.sleep;

/**
 * @author By ZengPeng
 */
public class 睡眠排序_最大值 {
    private static final ThreadPoolTaskExecutor THREAD_POOL;
    private static final int CORE_POOL_SIZE = 10;
    private static final int MAX_POOL_SIZE = 100;
    private static final int QUEUE_CAPACITY = 30;
    private static final int KEEP_ALIVE_TIME = 60;
    static {
        THREAD_POOL = new ThreadPoolTaskExecutor();
        THREAD_POOL.setCorePoolSize(CORE_POOL_SIZE);
        THREAD_POOL.setMaxPoolSize(MAX_POOL_SIZE);
        THREAD_POOL.setQueueCapacity(QUEUE_CAPACITY);
        THREAD_POOL.setKeepAliveSeconds(KEEP_ALIVE_TIME);
        THREAD_POOL.setThreadFactory(new ThreadFactory() {
            int count = 1;
            @Override
            public Thread newThread(Runnable runnable) {
                return new Thread(runnable, "并发处理线程---" + count++);
            }
        });
        THREAD_POOL.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //THREAD_POOL.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        THREAD_POOL.initialize();
    }

    //测试
    public static void main(String[] args) throws InterruptedException {
        int[] ints = {2, 1, 5, 3, 6, 4, 7,8,9,10,11,12};
        System.out.println(Arrays.toString(new 睡眠排序_最大值().sleepSorting(ints)));
    }

    /**
    题目：通过多线程+ sleep 排序

    分析：
        1.创建线程池 --系统支持的最大线程数 --防止多次调用排序时，频繁创建线程对时间的损耗
        2.添加开始标记:保证所有线程同时运行 boolean start;
        3.线程将排序好的值放回数组

    边界值 & 注意点：
       1.
     **/
    AtomicInteger index;
    boolean start = false;
    public int[] sleepSorting(int[] nums) throws InterruptedException {
        index=new AtomicInteger(0);
        for (int num : nums) {
            CompletableFuture.runAsync(() -> {
                try {
                    while (true){
                        if(start){
                            sleep(num*2);
                            nums[index.get()]=num;//回旋锁
                            index.getAndIncrement();
                            return;
                        }else {
                            sleep(1);
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, THREAD_POOL) ;
        }
        start =true;
        Thread.sleep(1000);//这里最好用 多线程的计数器来判断  ，没时间了  不优化啦
        THREAD_POOL.destroy();
        return nums;
    }
}
